﻿Public Class ClassDocument
    Public Enum FormatFichier
        Defaut = 0
        XML = 1
        UTF8 = 2
    End Enum

    'Un document chargé
    Public oItem As ListViewItem
    Public oInfo As System.IO.FileInfo
    Public iTrouve As Integer
    Public Stats As System.Collections.Generic.Dictionary(Of String, Integer)
    Public ZoomFactor As Single
    Public Historique As ClassHisto
    Private sChemin As String
    Private Format As FormatFichier
    Private bLoaded As Boolean
    Private sTitre As String
    Private sContenu As String
    Private sContenuRTF As String
    Private sContenuMarque As String
    Private sOriginal As String
    Private sUndoRTF As String
    Private sUndoMarque As String
    Private iSelStart, iSelLen As Integer
    Private ZeroConverted As Boolean
    'Propriétés pour la recherche de fichiers
    Private bChecked As Boolean
    Public Ordinateur As String

    Public Property Checked As Boolean
        Set(value As Boolean)
            If value <> bChecked Then AjouterHistoriqueMacro("scpEdit.ChercheFichiers.CheckTrouve " & Chr(34) & Me.Chemin & Chr(34) & ", " & value)
            bChecked = value
        End Set
        Get
            Return bChecked
        End Get
    End Property

    Public ReadOnly Property ID As String
        Get
            Return Me.sChemin & ";" & Me.sTitre
        End Get
    End Property

    Public Sub New(ByVal sFileName As String, ByVal Load As Boolean)
        Historique = New ClassHisto
        Historique.Cle = sFileName
        Me.ZeroConverted = False
        Me.sChemin = sFileName
        Me.Format = FormatFichier.Defaut
        If System.IO.Path.GetExtension(Chemin).ToUpper = ".XML" Then Me.Format = FormatFichier.XML
        Me.iTrouve = 0
        Me.sContenu = ""
        Me.sContenuRTF = ""
        Me.sContenuMarque = ""
        If Me.sChemin <> "" Then
            Me.oInfo = My.Computer.FileSystem.GetFileInfo(sFileName)
            Me.sTitre = My.Computer.FileSystem.GetName(Me.sChemin)
            If Load Then Me.ChargerContenu()
        Else
            oInfo = Nothing
            Dim iIndex As Integer = 0
            Do
                iIndex += 1
                Me.sTitre = "SansNom" & iIndex.ToString("0")
            Loop Until Not Form1.ListViewFichiers.Items.ContainsKey(Me.sTitre)
            bLoaded = False
        End If
        iSelStart = 0
        iSelLen = 0
        Stats = New System.Collections.Generic.Dictionary(Of String, Integer)
        Me.ZoomFactor = CSng(1)
        Me.bChecked = True
     End Sub

    Public Sub ChargerContenu()
        If My.Computer.FileSystem.FileExists(Me.sChemin) Then
            Try
                Me.oInfo = My.Computer.FileSystem.GetFileInfo(Me.sChemin)
                Select Case Me.Format
                    Case FormatFichier.XML
                        Dim oXMLDoc As New System.Xml.XmlDocument
                        oXMLDoc.XmlResolver = Nothing
                        oXMLDoc.Load(Me.sChemin)
                        Me.sContenu = oXMLDoc.OuterXml
                        Me.ReformaterXML()
                    Case FormatFichier.Defaut
                        Me.sContenu = Replace(My.Computer.FileSystem.ReadAllText(Me.sChemin, System.Text.Encoding.Default), vbCrLf, vbLf)
                        If Me.sContenu Is Nothing Then Me.sContenu = ""
                        If Me.sContenu.Contains(Chr(0)) Then
                            'MsgBox(Me.Chemin & " contient des caractères de code ascii zéro (0) qui ont été convertis en espaces (32) à la lecture.", MsgBoxStyle.Exclamation)
                            Me.sContenu = Me.sContenu.Replace(Chr(0), Chr(32))
                            Me.ZeroConverted = True
                        End If
                    Case FormatFichier.UTF8
                        Me.sContenu = Replace(My.Computer.FileSystem.ReadAllText(Me.sChemin, System.Text.Encoding.UTF8), vbCrLf, vbLf)
                End Select
                Me.sOriginal = Me.sContenu
                 bLoaded = True
            Catch ex As Exception
                If FormChercher.Visible Then
                    FormErreur.AjouteErreur("Erreur à la lecture de " & Me.sChemin & ":" & ex.Message)
                Else
                    MsgBox("Erreur à la lecture de " & Me.sChemin & ":" & ex.Message, MsgBoxStyle.Exclamation)
                End If
            End Try
        Else
            Me.sContenu = ""
        End If
    End Sub

    Public Sub Enregistrer()
        Try
            Dim sDossier As String = System.IO.Path.GetDirectoryName(Me.Chemin)
            If Not System.IO.Directory.Exists(sDossier) Then System.IO.Directory.CreateDirectory(sDossier)
            Dim oNewFileInfo As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(Me.Chemin)
            If Me.oInfo Is Nothing Then Me.oInfo = oNewFileInfo
            If Me.sOriginal <> Me.sContenu Then
                If My.Settings.ConserverHistorique Then
                    Dim oArc As New ClassArchive
                    oArc.CheminFichier = Me.Chemin
                    oArc.TitreFichier = Me.Titre
                    oArc.DateFichier = Me.oInfo.LastWriteTime.ToString
                    If oArc.DateFichier = "" Then oArc.DateFichier = Now().ToString
                    oArc.zContenu.SetValeur(sOriginal)
                    Me.Historique.Push(oArc)
                End If
                Me.sOriginal = Me.sContenu
            End If
            If oNewFileInfo.LastWriteTime <> Me.oInfo.LastWriteTime Then
                If MsgBox("Le fichier " & Me.Chemin & " a été mis à jour par un processus externe après son ouverture. Poursuire l'enregistrement ?", MsgBoxStyle.Question Or MsgBoxStyle.OkCancel) = MsgBoxResult.Cancel Then Exit Sub
            End If
            If Me.ZeroConverted Then
                Select Case MsgBox("Les caractères de code ascii zéro (0) de ce fichier ont été convertis en espaces (32) à la lecture. Reconvertir tous les espaces (32) en caractères zéros (0) à l'enregistrement ?", MsgBoxStyle.YesNoCancel)
                    Case MsgBoxResult.Yes
                        Me.sContenu = Me.sContenu.Replace(Chr(32), Chr(0))
                    Case MsgBoxResult.No
                        'Rien
                    Case MsgBoxResult.Cancel
                        Exit Sub
                End Select
            End If
            'Ajustement du format XML
            If System.IO.Path.GetExtension(Chemin).ToUpper = ".XML" Then
                Me.Format = FormatFichier.XML
            Else
                If Me.Format = FormatFichier.XML Then Me.Format = FormatFichier.Defaut
            End If
            Select Case Me.Format
                Case FormatFichier.XML
                    Dim oXMLDoc As New System.Xml.XmlDocument
                    oXMLDoc.XmlResolver = Nothing
                    oXMLDoc.LoadXml(Me.sContenu)
                    oXMLDoc.Save(Me.sChemin)
                Case FormatFichier.Defaut
                    My.Computer.FileSystem.WriteAllText(Me.sChemin, Replace(Me.sContenu, vbLf, vbCrLf), False, System.Text.Encoding.Default)
                Case FormatFichier.UTF8
                    My.Computer.FileSystem.WriteAllText(Me.sChemin, Replace(Me.sContenu, vbLf, vbCrLf), False, System.Text.Encoding.UTF8)
            End Select
            'Rafraichir
            Me.oInfo = My.Computer.FileSystem.GetFileInfo(Me.Chemin)
            'On revient avec des espaces
            If Me.ZeroConverted Then Me.sContenu = Me.sContenu.Replace(Chr(0), Chr(32))
        Catch ex As Exception
            MsgBox("Erreur à l'écriture de " & Me.sChemin & ":" & ex.Message, MsgBoxStyle.Exclamation)
        End Try
    End Sub

    Public Sub ClearStats()
        'Retirer des compteurs des marqueurs
        For Each sMarqueur As String In Me.Stats.Keys
            If Form1.ListViewMarqueurs.Items.ContainsKey(sMarqueur) Then
                Dim oMarqueur As ClassMarqueur = Form1.ListViewMarqueurs.Items(sMarqueur).Tag
                oMarqueur.Compteur -= Me.Stats(sMarqueur)
            End If
        Next
        Me.Stats.Clear()
    End Sub

    Public Sub EnregistrerSous(ByVal chemin As String)
        Me.sChemin = chemin
        Me.oInfo = Nothing
        Me.sTitre = My.Computer.FileSystem.GetName(Me.sChemin)
        Call Me.Enregistrer()
    End Sub

    Public ReadOnly Property Loaded() As Boolean
        Get
            Return Me.bLoaded
        End Get
    End Property

    Public ReadOnly Property Chemin() As String
        Get
            Return Me.sChemin.ToLower
        End Get
    End Property

    Public ReadOnly Property Titre() As String
        Get
            Return sTitre
        End Get
    End Property

    Public Property Contenu() As String
        Get
            If Not Me.Loaded And Me.Chemin <> "" Then Me.ChargerContenu()
            Return Me.sContenu
        End Get
        Set(ByVal value As String)
            Me.sContenu = Replace(value, vbCrLf, vbLf)
        End Set
    End Property

    Public Property ContenuRTF() As String
        Get
            Return Me.sContenuRTF
        End Get
        Set(ByVal value As String)
            Me.sUndoRTF = Me.sContenuRTF
            If Me.sUndoRTF = "" Then Me.sUndoRTF = value
            Me.sContenuRTF = value
        End Set
    End Property

    Public Property ContenuMarque() As String
        Get
            Return Me.sContenuMarque
        End Get
        Set(ByVal value As String)
            Me.sUndoMarque = Me.sContenuMarque
            If Me.sContenuMarque = "" Then Me.sContenuMarque = value
            Me.sContenuMarque = value
        End Set
    End Property

    Public Function GetIconeName() As String
        If Me.sChemin = "" Then
            GetIconeName = "Nouveau"
        Else
            GetIconeName = "Fichier"
        End If
    End Function

    Public Sub GetSel()
        Me.iSelStart = Form1.RichTextBox1.SelectionStart
        Me.iSelLen = Form1.RichTextBox1.SelectionLength
    End Sub

    Public Sub SetSel()
             Form1.RichTextBox1.SelectionStart = Me.iSelStart
        Form1.RichTextBox1.SelectionLength = Me.iSelLen
    End Sub

    Public Sub Undo()
        Me.sContenuRTF = Me.sUndoRTF
    End Sub

    Public ReadOnly Property Modifie() As Boolean
        Get
            Return (Me.sContenu <> Me.sOriginal)
        End Get
    End Property

    Public Sub RetourArriere()
        If Me.Historique.Count > 0 Then
            'Préparation de la fenêtre
            FormVersions.sActuel = Me.Contenu
            FormVersions.ListView1.Items.Clear()
            For Each oArc As ClassArchive In Me.Historique.Liste
                If oArc IsNot Nothing Then
                    Dim oItem As ListViewItem = FormVersions.ListView1.Items.Add(oArc.DateFichier)
                    If oItem.Text = "" Then oItem.Text = "Date inconnue"
                    oItem.Tag = oArc
                End If
            Next
            If FormVersions.ShowDialog() = DialogResult.OK Then
                Me.sContenu = FormVersions.oVersion.zContenu.GetValeur()
            End If
        Else
            MsgBox("Il n'y a aucune version historique disponible pour ce document!", MsgBoxStyle.Exclamation)
        End If
    End Sub

    Public Sub Reset()
        Me.sContenu = Me.sOriginal
    End Sub

    Private Sub ReformaterXML()
        Dim Doc As New System.Xml.XmlDocument()
        Doc.XmlResolver = Nothing
        Try
            Doc.LoadXml(Me.sContenu)
            Dim oMemStrm As New System.IO.MemoryStream()
            Dim oXmlWriter As New System.Xml.XmlTextWriter(oMemStrm, System.Text.Encoding.UTF8)
            oXmlWriter.Formatting = Xml.Formatting.Indented
            oXmlWriter.Indentation = 4
            oXmlWriter.IndentChar = " "
            Doc.Save(oXmlWriter)
            'oXmlWriter.Flush()
            Dim sXML As String = System.Text.Encoding.UTF8.GetString(oMemStrm.GetBuffer())
            If Asc(sXML(0)) = 63 Then sXML = sXML.Remove(0, 1)
            Me.sContenu = sXML
        Catch Ex As Exception
            MsgBox("Reformatage xml impossible: " & Ex.Message)
        End Try
    End Sub

    Public Function GetSecuriteXML(ByVal BasicRightsOnly As Boolean) As String
        If My.Computer.FileSystem.FileExists(Me.sChemin) Then
            Dim oSec As New MySecurity(Me.sChemin)
            Dim sSortie As String = Commun.Aligner(oSec.StringValue(BasicRightsOnly), ":")
            sSortie &= vbCrLf & vbCrLf
            sSortie &= oSec.GetLegende(BasicRightsOnly)
            Return sSortie
        Else
            Return ""
        End If
    End Function

    Public Function Supprimer() As Boolean
        Supprimer = True
        If My.Computer.FileSystem.FileExists(Me.sChemin) Then
            Try
                My.Computer.FileSystem.DeleteFile(Me.sChemin)
                Me.sOriginal = ""
            Catch ex As Exception
                MsgBox("Impossible de supprimer " & Me.sChemin & ": " & ex.Message, MsgBoxStyle.Exclamation)
                Supprimer = False
            End Try
        End If
    End Function

    Public Sub Lancer()
        'Exécuter la commande
        Call Me.Enregistrer()
        Dim oProcess As System.Diagnostics.Process
        Dim oStartInfo As New System.Diagnostics.ProcessStartInfo
        oStartInfo.FileName = Me.sChemin
        oStartInfo.UseShellExecute = True
        oStartInfo.WorkingDirectory = My.Computer.FileSystem.GetParentPath(Me.Chemin)
        oStartInfo.WindowStyle = ProcessWindowStyle.Normal
        oProcess = System.Diagnostics.Process.Start(oStartInfo)
        oProcess = Nothing
    End Sub
End Class
